﻿using System;
using System.Windows;
using SD.Libs.Navigation.Contracts;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;

namespace SD.Libs.Navigation
{
    // http://geekswithblogs.net/lbugnion/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx
    public class NavigationService : INavigationService
    {
        #region properties

        public Uri CurrentPageURI {
            get
            {
                return _mainFrame.CurrentSource;
            }
        }


        #endregion properties

        
        /// <summary>
        /// Raises the Navigating event (Occurs when navigation is fired from one page to another.).
        /// </summary>
        /// <param name="e">The <see cref="NavigationCancelEventHanlder"/> instance containing the event data.</param>
        protected virtual void OnNavigating(NavigatingCancelEventArgs e)
        {
            NavigatingCancelEventHandler eventHandler = Navigating;

            if (eventHandler != null)
            {
                eventHandler(this, e);
            }
        }
        

        private PhoneApplicationFrame _mainFrame;

        public event NavigatingCancelEventHandler Navigating;

        public void NavigateTo(Uri pageUri)
        {
            if (EnsureMainFrame())
            {
                _mainFrame.Navigate(pageUri);
            }
        }

        public void GoBack()
        {
            if (EnsureMainFrame()
                && _mainFrame.CanGoBack)
            {
                _mainFrame.GoBack();
            }
        }

        private bool EnsureMainFrame()
        {
            if (_mainFrame != null)
            {
                return true;
            }

            _mainFrame = Application.Current.RootVisual as PhoneApplicationFrame;

            if (_mainFrame != null)
            {

               
                // Could be null if the app runs inside a design tool
                _mainFrame.Navigating += (s, e) =>
                {
                    // Better approach
                    // 1st thread safe, we save the event handler in a local variable
                    // 2nd Separation of concerns
                    // 3rd you have the options to handle the event in the derived class directly
                    OnNavigating(e);
                    
                    // Prior code
                    /*
                    if (Navigating != null)
                    {
                        Navigating(s, e);
                    }*/
                };


                return true;
            }

            return false;
        }
    }
}
